/*
 * @Author: zf
 * @Last Modified by: zf
 * Description:
    1.列表展示组件
    2.slot: headerLeft =>表格顶部左侧信息;controlsBtn => 为表格列表操作列插槽
    3.dicType: 列表配置动态字典类型值
    4.dicProp: 列表配置动态字典的枚举字段
    5.filter: 列表配置固定枚举对象
    6.colOptionEnum: 动态枚举字典选项集合
    7.handlerClick: 列表表格内点击事件
    8.isSelection: 是否展示列表多选框 默认true
    9.isClearSelection: 是否在列表数据刷新时清除勾选状态 默认true
    10.isMarClass: 是否展示列表顶部信息或者按钮
    11.isShowTooltip: 是否在鼠标悬浮时展示信息
 */
<template>
  <div class="myTable" style="width: 100%;height: 100%">
    <div class="pms-zr-btnBox" :class="{'pms-zr-btnBox-btn': isMarClass}">
      <div class="slotContent">
        <slot name="headerLeft" />
      </div>
      <!-- btnBox-btn  btn_box -->
      <div v-if="tableOperation.length" class="btnBox-btns">
        <el-button
          v-for="(item, index) in tableOperation"
          :key="index"
          class="pms-zr-button-primary pms-zr-ClosedBtn"
          :type="item.type"
          size="small"
          @[eventName]="handleClick(item.fun, multipleSelection)"
        >
          {{ item.label }}
        </el-button>
      </div>
    </div>
    <el-table
      ref="tableRef"
      style="width: 100%;"
      :data="tableData"
      size="small"
      :current-row-key="id"
      :row-key="getRowKeys"
      :empty-text="emptyText"
      row-class-name="row"
      cell-class-name="column"
      tooltip-effect="dark"
      :highlight-current-row="true"
      fit
      border
      @selection-change="handleSelectionChange"
    >
      <!--这是是为了将表格设置成带有选择框的表格-->
      <el-table-column v-if="isSelection" type="selection" :reserve-selection="true" align="center" width="45"  :selectable="checkSelectable"/>
      <el-table-column align="center" type="index" label="序号" width="50" />
      <el-table-column
        v-for="(item, index) in columns"
        :key="index"
        align="center"
        :prop="item.prop"
        :width="item.width"
        :label="item.label"
        :show-overflow-tooltip="item.isShowTooltip ? false : true"
      >
        <template slot="header" slot-scope="{ column }">
          <el-tooltip
            effect="dark"
            :content="column.label"
            placement="top"
          >
            <div class="header-tooltip">{{ column.label }}</div>
          </el-tooltip>
        </template>
        <template #default="{ row, $index }">
          <slot :scope="row" :index="$index" :name="item.prop">
            <div class="rowItem" @click="handlerClick(row, item.prop)">
              {{ row[item.prop] | filterData(item, colOptionEnum[item.dicType]) }}
            </div>
          </slot>
        </template>
      </el-table-column>
      <slot name="controlsBtn" />
    </el-table>
  </div>
</template>

<script>
import { msgInfoEl } from '@/utils'
import store from '@/store'

export default {
    name: 'MyTable',
    filters: {
        // 列表默认展示数据的处理
        filterData(prop, item, dicList) {
            let propName = ''
            if (!prop && prop !== 0) {
                return ''
            }
            if (prop === '-') {
                return prop
            }
            if (item.dicType && Array.isArray(dicList) && dicList.length) {
                const propObj = dicList.find(sign => sign[item.dicProp.value] === prop) || {}
                propName = JSON.stringify(propObj) !== '{}' ? propObj[item.dicProp.label] : ''
                // propName = dicList.find(sign => sign[item.dicProp.value] === prop)[item.dicProp.label]
            } else {
                if (item.filter && JSON.stringify(item.filter) !== '{}') {
                    propName = item.filter[String(prop)] || ''
                } else {
                    propName = prop
                }
            }
            return propName || ''
        }
    },
    // 因为是子组件，要接受父组件传递的数据，所以这里我们定义props
    props: {
        // 返回数据id
        id: {
            type: [String, Number],
            required: true,
            default: ''
        },
        // 父组件传递过来的表格数据
        tableData: {
            type: Array,
            default: () => []
        },
        // 父组件传递过来的表头数据
        columns: {
            type: Array,
            default: () => []
        },
        // 父组件传递过来的操作按钮数据
        tableOperation: {
            type: Array,
            default: () => []
        },
        // 列表数据枚举字段选项集
        colOptionEnum: {
            type: Object,
            default: () => ({})
        },
        isSelection: {
            type: Boolean,
            default: true
        },
        isMarClass: {
            type: Boolean,
            default: false
        },
        isClearSelection: {
            type: Boolean,
            default: true
        },
        emptyText: {
            type: String,
            default: '暂无数据'
        },
        isShowCheckbox: {
            type: Boolean,
            default: false
        }
    },
    data() {
        return {
            eventName: 'click', // 点击按钮绑定的方法，这样写法也可以去绑定一些其他的比如change等方法
            multipleSelection: [], // 这个数组用来保存被选择行的数据，顺序是按照你勾选的顺序来排序的
            // 按钮配置 0 => 不需要勾选，1 => 支持单选，2 => 支持多选
            btnConfig: {
                inquire: 0, // 查询
                add: 0, // 新增
                edit: 1, // 编辑
                delete: 2, // 删除
                visa: 1, // 验签
                void: 1, // 作废
                derive: 0, // 导出
                conDesc: 0, // 规则配置说明
                assign: 1, // 指派签署人
                upload: 0, // 上传
                download: 2, // 下载
                renewal: 1, // 替换
                confirmSign: 0, // 确认签署
                archivist: 0 ,// 归档
                cancelassign:1,//撤销指派
            }
        }
    },
    watch: {
        tableData: {
            handler(newVal) {
                if (newVal.length && this.isClearSelection) {
                    this.$refs.tableRef.clearSelection()
                }
            },
            deep: true
        }
    },
    methods: {
        // 多选框是否可选
        checkSelectable(row, index){
            if(!this.isShowCheckbox){return true}
            if(row.state==='3'&&row.fileState==='01'){
                return true
            }else{
                return false
            }
        },
        // @selection-change方法可以监听到表格里哪一行被选中，类型是数组;
        // 然后我们将它赋值给定义好的 multipleSelection
        handleSelectionChange(rowList) {
            this.multipleSelection = rowList
            this.$emit('handleSelection', rowList)
            store.commit('settings/setTableCheckData', rowList)
        },
        // 数据id
        getRowKeys(row) {
            return row[this.id]
        },
        // 用于多选表格，切换某一行的选中状态
        toggleRowEvent(row, flag) {
            if (Array.isArray(row)) {
                row.forEach(item => {
                    this.$refs.tableRef.toggleRowSelection(item, flag)
                })
            } else {
                this.$refs.tableRef.toggleRowSelection(row, flag)
            }
        },
        // 清空选中
        clearSelection() {
            this.$refs.tableRef.clearSelection()
        },
        // 用于多选表格，切换所有行的选中状态
        toggleAllSelection() {
            this.$refs.tableRef.toggleAllSelection()
        },
        // 列表表格点击事件
        handlerClick(row, prop) {
            this.$emit('rowClick', row, prop)
        },
        // 动态绑定操作按钮的点击事件(按钮是父组件传递过来循环出来的,所以我们给按钮定义一个方法)
        // 接收两个参数，一个是fun(string类型)，一个是row（array类型，也就是我们选中行的数据）
        // 这里的某个按钮时传递的参数
        // 比如我点击的是编辑，那这时的fun就是 'edit',执行的方法就是下边的this.edit（row）
        // add => 新增，edit => 编辑，delete => 删除，assign => 指派签署人,upload => 上传，download => 下载
        handleClick(fun, row) {
            const type = this.btnConfig[fun]
            if (type === 1) {
                this.singleChoice(fun, row)
                return
            }
            if (type === 2) {
                this.multipleChoice(fun, row)
                return
            }
            this.uncheck(fun, row)
        },
        // 单条数据选择
        singleChoice(fun, row) {
            if (!row.length) {
                msgInfoEl({
                    type: 'info',
                    message: '请勾选数据后操作'
                })
                return false
            }
            if (row.length > 1) {
                msgInfoEl({
                    type: 'info',
                    message: '当前仅支持单条数据操作'
                })
                return false
            }
            this.$emit('propClick', fun, row)
        },
        // 多条数据选择
        multipleChoice(fun, row) {
            if (!row.length) {
                msgInfoEl({
                    type: 'info',
                    message: '请勾选数据后操作'
                })
                return false
            }
            this.$emit('propClick', fun, row)
        },
        // 不用选择数据
        uncheck(fun, row) {
            this.$emit('propClick', fun, row)
        }
    }
}
</script>

<style lang="scss" scoped>
.slotContent {
    // flex: 1;
    width: 100%;
}
.btnBox-btns {
    width: auto;
    display: flex;
}
::v-deep .pms-button-primary {
    color: #fff;
}
.header-tooltip {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.rowItem {
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
::v-deep .el-table__empty-text{
  line-height: 100px !important;
}
</style>

